{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# This is the Baseline Model for doing Machine Learning in Birdcall Recognition\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "import plotly.express as px\n",
    "import librosa\n",
    "\n",
    "import pywt\n",
    "from statsmodels.robust import mad\n",
    "from warnings import filterwarnings; filterwarnings('ignore')\n",
    "\n",
    "import plotly.express as px\n",
    "import plotly.graph_objects as go\n",
    "import plotly.figure_factory as ff\n",
    "from plotly.subplots import make_subplots\n",
    "from scipy.io import wavfile\n",
    "import subprocess\n",
    "\n",
    "from tqdm.notebook import tqdm\n",
    "import librosa\n",
    "\n",
    "PATH = '../input/birdsong-recognition/'\n",
    "TEST_FOLDER = '../input/birdsong-recognition/test_audio/'\n",
    "os.listdir(PATH)\n",
    "RANDOM_SEED = 4444"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "train = pd.read_csv(os.path.join(PATH, 'train.csv'))\n",
    "test = pd.read_csv(os.path.join(PATH, 'test.csv'))\n",
    "submission = pd.read_csv(os.path.join(PATH, 'sample_submission.csv'))\n",
    "example_test_audio_summary = pd.read_csv(os.path.join(PATH, 'example_test_audio_summary.csv'))\n",
    "example_test_audio_metadata = pd.read_csv(os.path.join(PATH, 'example_test_audio_metadata.csv'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def load_test_clip(path, start_time, duration=5):\n",
    "    return librosa.load(path, offset=start_time, duration=duration)[0]\n",
    "\n",
    "def make_prediction(y, le, model):\n",
    "    feats = np.array([np.min(y), np.max(y), np.mean(y), np.std(y)]).reshape(1, -1)\n",
    "    return le.inverse_transform(model.predict(feats))[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Below is for the train attribute generation. Note these values selected are really **naive**.\n",
    "*TODO: OPTIMIZE IT*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/plain": "HBox(children=(FloatProgress(value=0.0, max=264.0), HTML(value='')))",
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "54a6c00cd9e046b4985a5dbfd817b2c5"
      }
     },
     "metadata": {}
    },
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "\n"
    }
   ],
   "source": [
    "train = pd.DataFrame(columns = ['min', 'max', 'mean', 'std', 'target'])\n",
    "nRows = 0\n",
    "for bird in tqdm(os.listdir(os.path.join(PATH, 'train_audio'))):\n",
    "    for audio in  os.listdir(os.path.join(PATH, 'train_audio', bird)):\n",
    "        path = os.path.join(PATH, 'train_audio', bird, audio)\n",
    "        subprocess.call(['ffmpeg', '-y', '-i', f'{path}', f'../temp/temp.wav'])\n",
    "        _, y = wavfile.read('../temp/temp.wav')\n",
    "        train.loc[nRows] = [np.min(y), np.max(y), np.mean(y), np.std(y), bird]\n",
    "        nRows += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import LabelEncoder\n",
    "le = LabelEncoder()\n",
    "train['target'] = le.fit_transform(train['target'].values)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The Model that we used here is the RandomForest Classifier \n",
    "*TODO: OPTIMIZE IT*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,\n                       criterion='gini', max_depth=6, max_features='auto',\n                       max_leaf_nodes=None, max_samples=None,\n                       min_impurity_decrease=0.0, min_impurity_split=None,\n                       min_samples_leaf=1, min_samples_split=2,\n                       min_weight_fraction_leaf=0.0, n_estimators=100,\n                       n_jobs=None, oob_score=False, random_state=4444,\n                       verbose=0, warm_start=False)"
     },
     "metadata": {},
     "execution_count": 11
    }
   ],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "model = RandomForestClassifier(max_depth = 6, random_state = RANDOM_SEED)\n",
    "model.fit(train.drop(columns = 'target'), train['target'].values) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-12-06dc8a1b65aa>, line 1)",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-12-06dc8a1b65aa>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    Note Below, it trys to read the test.csv's full data. If the test.csv is not complete,\u001b[0m\n\u001b[1;37m             ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "Note Below, it trys to read the test.csv's full data. If the test.csv is not complete"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "error",
     "ename": "IndentationError",
     "evalue": "unexpected indent (<ipython-input-15-89a528d07d94>, line 2)",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-15-89a528d07d94>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    preds = []\u001b[0m\n\u001b[1;37m    ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m unexpected indent\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    preds = []\n",
    "    for index, row in test.iterrows():\n",
    "        # Get test row information\n",
    "        site = row['site']\n",
    "        start_time = row['seconds'] - 5\n",
    "        row_id = row['row_id']\n",
    "        audio_id = row['audio_id']\n",
    "\n",
    "        # Get the test sound clip\n",
    "        if site == 'site_1' or site == 'site_2':\n",
    "            y = load_test_clip(TEST_FOLDER + audio_id + '.mp3', start_time)\n",
    "        else:\n",
    "            y = load_test_clip(TEST_FOLDER + audio_id + '.mp3', 0, duration=None)\n",
    "\n",
    "        # Make the prediction\n",
    "        pred = make_prediction(y, le, model)\n",
    "\n",
    "        # Store prediction\n",
    "        preds.append([row_id, pred])\n",
    "    \n",
    "except:\n",
    "     preds = pd.read_csv('../input/birdsong-recognition/sample_submission.csv')\n",
    "print(preds)\n",
    "preds = pd.DataFrame(preds, columns=['row_id', 'birds'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "preds.to_csv('submission.csv', index=False) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python_defaultSpec_1594543328186",
   "display_name": "Python 3.7.6 64-bit ('base': conda)"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}